How do you overload the = operator for custom types to the right?
struct MyType {}
void ::= (int &Value, MyType MyTypeVar) { Value = 5 }
MyType NewMyType
int Test = NewMyType
print "Test : " Test "\n"
SystemAdmin - Mon Feb 14 11:56:08 EST 2011 |
Re: Overload the = operator
struct MyType {}
int& ::= (int& intValue, MyType myTypeInstance) {
intValue = (int addr_ myTypeInstance);
return intValue;
}
MyType& ::= (MyType& myTypeInstanceRef, int intValue) {
myTypeInstanceRef = (MyType addr_ intValue);
return myTypeInstanceRef;
}
int intOf(MyType myTypeInstance) {
return (int addr_ myTypeInstance);
}
MyType myTypeInstance;
int intVal;
myTypeInstance = 777;
intVal = myTypeInstance;
print "intVal = " (intVal) "\n";
print "myTypeInstance = " (intOf(myTypeInstance)) "\n";
|
Re: Overload the = operator
Note however that a direct assignment during declaration will NOT (when I remember right from past experiments) call the assignment operator! Therefore I strongly recommend not to overwrite the assignment operator, but to use some other operator instead, like <- or <=. Also the ::= operator will shadow your DxlObject ::= operator, another reason not to use it. You can get some very hard to find errors from this ;-) All in all the below code makes it clear, that DOORS does not implement ::= operator overloading properly.
struct MyType {}
void ::= (MyType &MyTypeVar, MyType blub) { print "MyType = MyType\n"}
void ::= (MyType &MyTypeVar, int a) { print "Hallo -> " a "\n"}
// this works
MyType NewMyType = null
NewMyType = 4
// this wont even compile:
// MyType vvv = 15
// this compiles but does not call the operator!
print "In Declaration: \n"
MyType testtest = NewMyType
// This will call the operator ...
print "After declaration:\n"
testtest = NewMyType
print "\n\n"
// Watch out for using ::= operators ...
DxlObject x = new()
x->"ohno" = 1
int a = (x->"ohno") int
print "Uh oh: " a "\n"
/* prints:
Hallo -> 4
In Declaration:
After declaration:
MyType = MyType
Hallo -> 1
Uh oh: 0
*/
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Overload the = operator
Although I have yet to use the "return value" of the ::=(p1&,p2) function, it should be p1 (not p1& as I erroneously showed in previous post)
struct MyType {}
int ::= (int& intRef, MyType myTypeInstance) {
// local int variable gets the myTypeInstance content
int intContent = (int addr_ myTypeInstance);
// The passed in int reference gets the intContent
// This is what does the LHS = RHS assignment
intRef = intContent;
// Return the int content for good measure (seldom used)
return (intContent);
}
MyType ::= (MyType& myTypeInstanceRef, int intValue) {
// local MyType variable gets the intValue content
MyType myTypeInstance = (MyType addr_ intValue)
// The passed in MyType reference gets the myTypeInstance content
// This is what does the LHS = RHS assignment
myTypeInstanceRef = myTypeInstance;
// Return the MyType content for good measure (seldom used)
// Allows the below to work (where j is int):
// print "myTypeInstance = " (j = myTypeInstance) "\n";
return (myTypeInstance);
}
int intOf(MyType myTypeInstance) {
return (int addr_ myTypeInstance);
}
MyType myTypeInstance = null;
int intVal = null;
myTypeInstance = 777;
intVal = myTypeInstance;
print "intVal = " (intVal) "\n";
print "myTypeInstance = " (intOf(myTypeInstance)) "\n";
int j;
// The below uses the "return value" (see why I don't use it?)
print "myTypeInstance = " (j = myTypeInstance) "\n";
|
Re: Overload the = operator SystemAdmin - Mon Feb 14 16:34:19 EST 2011
Although I have yet to use the "return value" of the ::=(p1&,p2) function, it should be p1 (not p1& as I erroneously showed in previous post)
struct MyType {}
int ::= (int& intRef, MyType myTypeInstance) {
// local int variable gets the myTypeInstance content
int intContent = (int addr_ myTypeInstance);
// The passed in int reference gets the intContent
// This is what does the LHS = RHS assignment
intRef = intContent;
// Return the int content for good measure (seldom used)
return (intContent);
}
MyType ::= (MyType& myTypeInstanceRef, int intValue) {
// local MyType variable gets the intValue content
MyType myTypeInstance = (MyType addr_ intValue)
// The passed in MyType reference gets the myTypeInstance content
// This is what does the LHS = RHS assignment
myTypeInstanceRef = myTypeInstance;
// Return the MyType content for good measure (seldom used)
// Allows the below to work (where j is int):
// print "myTypeInstance = " (j = myTypeInstance) "\n";
return (myTypeInstance);
}
int intOf(MyType myTypeInstance) {
return (int addr_ myTypeInstance);
}
MyType myTypeInstance = null;
int intVal = null;
myTypeInstance = 777;
intVal = myTypeInstance;
print "intVal = " (intVal) "\n";
print "myTypeInstance = " (intOf(myTypeInstance)) "\n";
int j;
// The below uses the "return value" (see why I don't use it?)
print "myTypeInstance = " (j = myTypeInstance) "\n";
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Overload the = operator Mathias Mamsch - Tue Feb 15 04:10:33 EST 2011 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Overload the = operator SystemAdmin - Tue Feb 15 07:20:34 EST 2011
Declaring a "::=" operator will not break all standard assignments. It will specially break the DxlObject assignment. I don't think other assignments will be broken. For me the problem looks as followed: The DxlObject perms are defined as: _x ::-> (DxlObject obj, string fieldName) // problem perm DxlObjectLHS ::-> (DxlObject obj, string fieldName) void ::= (DxlObjectLHS lhs, _x newValue)
struct MyType {}
int ::=(MyType x, int val) { print "Test:" val "\n"; return 0 }
DxlObject x = new()
x->"Hallo" = 123
// the (x->"Hallo") will be translated to the _x type, which matches MyType
// this works!
(DxlObjectLHS (x->"Hallo2")) = 234
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Overload the = operator Mathias Mamsch - Tue Feb 15 07:53:29 EST 2011
Declaring a "::=" operator will not break all standard assignments. It will specially break the DxlObject assignment. I don't think other assignments will be broken. For me the problem looks as followed: The DxlObject perms are defined as: _x ::-> (DxlObject obj, string fieldName) // problem perm DxlObjectLHS ::-> (DxlObject obj, string fieldName) void ::= (DxlObjectLHS lhs, _x newValue)
struct MyType {}
int ::=(MyType x, int val) { print "Test:" val "\n"; return 0 }
DxlObject x = new()
x->"Hallo" = 123
// the (x->"Hallo") will be translated to the _x type, which matches MyType
// this works!
(DxlObjectLHS (x->"Hallo2")) = 234
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Ok, Thanks. // All fail int intValue = NewType int intValue => NewType int intValue <- NewType |
Re: Overload the = operator SystemAdmin - Tue Feb 15 08:39:41 EST 2011
Ok, Thanks. // All fail int intValue = NewType int intValue => NewType int intValue <- NewType Yes with the <- operators you would be forced to do int x; x <- myType Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Overload the = operator Mathias Mamsch - Tue Feb 15 09:02:24 EST 2011 Yes with the <- operators you would be forced to do int x; x <- myType Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS Mathias, in a prior post in this topic where you remarked:
I concur that your example does indeed illustrate a serious problem. Please clarify the perm that is being matched and remark on some other mysterious fun facts.
SomeType ::= (SomeType&, SomeOtherType); // usage: some = someOther;
struct MyType66 {}
MyType66 ::= (MyType66&, int);
// later we have …
MyType66 my66;
int iFour = 4;
my66 = iFour; // calls the overloaded (MyType66&, int)
|
Re: Overload the = operator SystemAdmin - Tue Feb 15 11:22:52 EST 2011 Mathias, in a prior post in this topic where you remarked:
I concur that your example does indeed illustrate a serious problem. Please clarify the perm that is being matched and remark on some other mysterious fun facts.
SomeType ::= (SomeType&, SomeOtherType); // usage: some = someOther;
struct MyType66 {}
MyType66 ::= (MyType66&, int);
// later we have …
MyType66 my66;
int iFour = 4;
my66 = iFour; // calls the overloaded (MyType66&, int)
Anyway coming again to the "problem perm" and the breaking DxlObject assigments, if the parser comes to a statement: myDxlObject->myString = intValue, it has to get the right perm for the two operators ::-> and ::=. For ::-> it has two alternatives. For the assignments there are several possibilities. So it will (depth first recursively) try all assignments that have an int value on the right hand side. For each assignment it will try to find a ::-> perm that takes DxlObject and string as parameter and yields a compatible return value. As soon you define your own assignment operator that one will take precedence in the search order. And since unfortunately the _x ::-> operator will match to any type, the parser seemingly chooses the first valid combination (instead of checking for others and issuing a ambiguous statement error). This is all guesswork, by the way. So the DxlObjectLHS thing is just the way you anable those var.blah = blub or var->blah = blub or function MyType[val] syntax in DXL (and this syntax is probably the reason why . and -> take precedence over other operators by the way, so you would not need to put parenthesis). DxlObjectLHS is a undocumented type which will store the DxlObject handle and the string value, and pass that to the assignent operator, which will extract the string value, the dxlobject handle from the DxlObjectLHS and then do the assignment. Usually the _x ::-> perm is used when you do right hand assignments int x = (MyDxlObject->myString) int and it will extract the value of the DxlObject. In this case the _x variant of ::-> will be used and casted to int since there is no ::=(int, DxlObjectLHS) perm. In case of left hand assignments however ::=(DxlObjectLHS, _x) should be always be used. Since both ::-> perms for DxlObject are ambiguous the syntax only works because of the search order, i.e. in assigments the parser will consider the DxlObjectLHS operator first. No idea if I am anywhere near the truth here. The whole thing is probably even more complicated. Regards, Mathias Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Overload the = operator Mathias Mamsch - Tue Feb 15 12:31:09 EST 2011 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS Thanks. This is great information even if some of it is empirical. This is a regular circus. How I wish could have a sodium pentothal party with some of those original DXL architects and find out what they were thinking. Curiously, the DxlObjectLHS parameter is passed by value and not by reference like the other assignment overload functions. I can only assume it must already be a reference (have a reference to the DxlObject) in order to work. Do you know the field structure? |
Re: Overload the = operator Mathias Mamsch - Tue Feb 15 12:31:09 EST 2011 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Adding a DxlObjectLHS typecast to force the proper DXL native perm call will undo the bug. I think the bug stems from DXL authors using the same syntax to set/get DxlObject fields depending on context.
struct MyType {}
void ::= (MyType &MyTypeVar, MyType blub) { print "MyType = MyType\n"}
void ::= (MyType &MyTypeVar, int a) { print "Hallo -> " a "\n"}
// this works
MyType NewMyType = null
NewMyType = 4
// this wont even compile:
// MyType vvv = 15
// this compiles but does not call the operator!
print "In Declaration: \n"
MyType testtest = NewMyType
// This will call the operator ...
print "After declaration:\n"
testtest = NewMyType
print "\n\n"
// Watch out for using ::= operators ...
DxlObject x = new()
x->"ohno" = 1
int a = (x->"ohno") int
print "Uh oh: " a "\n"
(DxlObjectLHS x->"thisWorks") = 2
int b = (x->"thisWorks") int
print "thisWorks: " b "\n"
/* prints:
Hallo -> 4
In Declaration:
After declaration:
MyType = MyType
Hallo -> 1
Uh oh: 0
thisWorks: 2
*/
|
Re: Overload the = operator |
Re: Overload the = operator SystemAdmin - Fri Feb 18 08:19:25 EST 2011 |